package com.bdqn.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Arrays;

/**
 * 示例2：通过反射获取类的构造函数
 *
 * @author LILIBO
 * @since 2022-09-15
 */
public class Demo02 {

    public static void main(String[] args) {
        // 通过Class.forName()方法获取Class对象
        Class clazz = null;
        try {
            clazz = Class.forName("com.bdqn.pojo.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        // 获得所有public的构造函数
        System.out.println("所有public（公开的）构造函数: ");
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor c : constructors) {
            System.out.println("构造函数: " + c.getName() + " " + Arrays.toString(c.getParameterTypes()));
        }

        // 获得指定参数列表public的构造函数
        System.out.println("指定参数列表public的构造函数: ");
        try {
            // 表示获得第一个参数是String类型，第二个参数是int类型的构造函数
            Constructor c = clazz.getConstructor(String.class, int.class);
            System.out.println("构造函数: " + c.getName() + " 参数个数: " + c.getParameterCount());
        } catch (NoSuchMethodException e) {
            // 方法找不到异常
            e.printStackTrace();
        }

        // 获得所有构造函数（public、private等）
        System.out.println("所有构造函数（public、private等）: ");
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for (Constructor c : declaredConstructors) {
            int modifiers = c.getModifiers(); // 访问修饰符代码
            String modifierStr = "default(package)";
            // &&并且的意思，&表示二进制与运算 |表示二进制或运算
            // 2 | 1 == 3 // 先转二进制 10 | 01 再运算（同位比较，只要有1就是1，否则为0）获得结果 11 转回十进制结果为 3
            // 2 & 1 == 0 // 先转二进制 10 | 01 再运算（同位比较，全部为1才是1，否则为0）获得结果 00 转回十进制结果为 0
            if ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC) {
                modifierStr = "public";
            } else if ((modifiers & Modifier.PROTECTED) == Modifier.PROTECTED) {
                modifierStr = "protected";
            } else if ((modifiers & Modifier.PRIVATE) == Modifier.PRIVATE) {
                modifierStr = "private";
            } else {
                modifierStr = "default(package)";
            }
            // 获取构造函数参数列表 getParameterTypes()
            System.out.println("构造函数: " + modifierStr + " " + c.getName() + " " + Arrays.toString(c.getParameterTypes()));
        }
    }
}
